/**
 * 扩展验证规则 - 新增更多题型的验证规则
 * 这些规则将被整合到 verify-all-topics.js 中
 */

function near(a,b){ return Math.abs(Number(a)-Number(b)) < 1e-6; }
function round(v, decimals = 3){ return Math.round(v * Math.pow(10, decimals)) / Math.pow(10, decimals); }

// ========== 新增验证器函数 ==========

// 1. 盈亏问题验证器
function verifyProfitLoss(stem, answer){
  // 匹配：每人分N个，多M个；每人分X个，少Y个
  const m1 = stem.match(/每人分(\d+)个.*?多(\d+)个.*?每人分(\d+)个.*?少(\d+)个/);
  if(m1){
    const [,n1,surplus,n2,shortage] = m1.map(Number);
    // 人数 = (surplus + shortage) / (n2 - n1)
    // 物品数 = 人数 * n1 + surplus
    const people = (surplus + shortage) / (n2 - n1);
    const items = people * n1 + surplus;
    if(Number.isInteger(people) && people > 0){
      if(near(answer[0], people) && (answer.length === 1 || near(answer[1], items))){
        return {ok:true};
      }
      return {ok:false, fix: answer.length === 1 ? [people] : [people, items]};
    }
  }
  
  // 匹配：每人分N个，剩M个；每人分X个，缺Y个
  const m2 = stem.match(/每人分(\d+)个.*?剩(\d+)个.*?每人分(\d+)个.*?缺(\d+)个/);
  if(m2){
    const [,n1,surplus,n2,shortage] = m2.map(Number);
    const people = (surplus + shortage) / (n2 - n1);
    const items = people * n1 + surplus;
    if(Number.isInteger(people) && people > 0){
      if(near(answer[0], people) && (answer.length === 1 || near(answer[1], items))){
        return {ok:true};
      }
      return {ok:false, fix: answer.length === 1 ? [people] : [people, items]};
    }
  }
  
  return null;
}

// 2. 植树问题验证器
function verifyTreePlanting(stem, answer){
  // 两端都栽：棵数 = 间隔数 + 1
  const m1 = stem.match(/长(\d+)米.*?每隔(\d+)米.*?两端都栽/);
  if(m1){
    const [,length,interval] = m1.map(Number);
    const trees = length / interval + 1;
    if(Number.isInteger(trees)){
      return near(answer[0], trees) ? {ok:true} : {ok:false, fix:[trees]};
    }
  }
  
  // 两端都不栽：棵数 = 间隔数 - 1
  const m2 = stem.match(/长(\d+)米.*?每隔(\d+)米.*?两端都不栽/);
  if(m2){
    const [,length,interval] = m2.map(Number);
    const trees = length / interval - 1;
    if(Number.isInteger(trees)){
      return near(answer[0], trees) ? {ok:true} : {ok:false, fix:[trees]};
    }
  }
  
  // 一端栽：棵数 = 间隔数
  const m3 = stem.match(/长(\d+)米.*?每隔(\d+)米.*?一端栽/);
  if(m3){
    const [,length,interval] = m3.map(Number);
    const trees = length / interval;
    if(Number.isInteger(trees)){
      return near(answer[0], trees) ? {ok:true} : {ok:false, fix:[trees]};
    }
  }
  
  // 环形：棵数 = 间隔数
  const m4 = stem.match(/周长(\d+)米.*?每隔(\d+)米.*?环形|圆形|围成/);
  if(m4){
    const [,length,interval] = m4.map(Number);
    const trees = length / interval;
    if(Number.isInteger(trees)){
      return near(answer[0], trees) ? {ok:true} : {ok:false, fix:[trees]};
    }
  }
  
  return null;
}

// 3. 归一问题验证器
function verifyUnitRate(stem, answer){
  // 匹配：A个B用C，D个B用多少
  const m1 = stem.match(/(\d+)个.*?用.*?(\d+).*?(\d+)个.*?用/);
  if(m1){
    const [,count1,amount1,count2] = m1.map(Number);
    const unitRate = amount1 / count1;
    const result = unitRate * count2;
    return near(answer[0], result) ? {ok:true} : {ok:false, fix:[round(result)]};
  }
  
  // 匹配：A元买B个，C元买多少个
  const m2 = stem.match(/(\d+)元.*?买.*?(\d+)个.*?(\d+)元.*?买/);
  if(m2){
    const [,money1,count1,money2] = m2.map(Number);
    const unitPrice = money1 / count1;
    const result = money2 / unitPrice;
    return near(answer[0], result) ? {ok:true} : {ok:false, fix:[round(result)]};
  }
  
  return null;
}

// 4. 牛吃草问题验证器
function verifyGrassCow(stem, answer){
  // 基础牛吃草：草量 = 原有草量 + 生长速度 × 时间
  // (牛数 - 生长速度) × 时间 = 原有草量
  const m1 = stem.match(/(\d+)头牛.*?(\d+)天.*?吃完.*?(\d+)头牛.*?(\d+)天.*?吃完/);
  if(m1){
    const [,cow1,day1,cow2,day2] = m1.map(Number);
    // 设原有草量为Y，生长速度为X
    // (cow1 - X) * day1 = Y
    // (cow2 - X) * day2 = Y
    // 解得：X = (cow1*day1 - cow2*day2) / (day1 - day2)
    const growthRate = (cow1*day1 - cow2*day2) / (day1 - day2);
    const originalGrass = (cow1 - growthRate) * day1;
    
    // 如果题目问多少头牛多少天吃完
    const m2 = stem.match(/(\d+)头牛.*?多少天/);
    if(m2){
      const [,cow3] = m2.map(Number);
      const days = originalGrass / (cow3 - growthRate);
      if(days > 0 && Number.isFinite(days)){
        return near(answer[0], days) ? {ok:true} : {ok:false, fix:[round(days)]};
      }
    }
  }
  
  return null;
}

// 5. 数论基础验证器
function verifyNumberTheory(stem, answer){
  // 质数判断
  const m1 = stem.match(/(\d+)是质数吗|(\d+)是不是质数/);
  if(m1){
    const num = Number(m1[1] || m1[2]);
    const isPrime = (n) => {
      if(n < 2) return false;
      for(let i = 2; i <= Math.sqrt(n); i++){
        if(n % i === 0) return false;
      }
      return true;
    };
    const result = isPrime(num);
    const expected = answer[0] === '是' || answer[0] === true || answer[0] === 1;
    return result === expected ? {ok:true} : {ok:false, fix:[result ? '是' : '不是']};
  }
  
  // 最大公约数
  const m2 = stem.match(/(\d+)和(\d+)的最大公约数/);
  if(m2){
    const [,a,b] = m2.map(Number);
    const gcd = (x, y) => y === 0 ? x : gcd(y, x % y);
    const result = gcd(a, b);
    return near(answer[0], result) ? {ok:true} : {ok:false, fix:[result]};
  }
  
  // 最小公倍数
  const m3 = stem.match(/(\d+)和(\d+)的最小公倍数/);
  if(m3){
    const [,a,b] = m3.map(Number);
    const gcd = (x, y) => y === 0 ? x : gcd(y, x % y);
    const lcm = (x, y) => (x * y) / gcd(x, y);
    const result = lcm(a, b);
    return near(answer[0], result) ? {ok:true} : {ok:false, fix:[result]};
  }
  
  return null;
}

// 6. 二次函数验证器
function verifyQuadraticFunction(stem, answer){
  // 匹配：y = ax² + bx + c，求顶点坐标
  const m1 = stem.match(/y\s*=\s*(-?\d+)x²\s*\+\s*(-?\d+)x\s*\+\s*(-?\d+).*?顶点/);
  if(m1){
    const [,a,b,c] = m1.map(Number);
    const x = -b / (2 * a);
    const y = a * x * x + b * x + c;
    if(Array.isArray(answer[0])){
      if(near(answer[0][0], x) && near(answer[0][1], y)){
        return {ok:true};
      }
      return {ok:false, fix:[[round(x, 2), round(y, 2)]]};
    }
  }
  
  // 匹配：y = ax² + bx + c，求对称轴
  const m2 = stem.match(/y\s*=\s*(-?\d+)x²\s*\+\s*(-?\d+)x\s*\+\s*(-?\d+).*?对称轴/);
  if(m2){
    const [,a,b,c] = m2.map(Number);
    const x = -b / (2 * a);
    const result = `x=${round(x, 2)}`;
    if(answer[0] === result || near(answer[0], x)){
      return {ok:true};
    }
    return {ok:false, fix:[result]};
  }
  
  return null;
}

// 7. 解直角三角形验证器
function verifyRightTriangle(stem, answer){
  // 匹配：已知两边求第三边（勾股定理）
  const m1 = stem.match(/直角三角形.*?两直角边.*?(\d+).*?(\d+).*?斜边/);
  if(m1){
    const [,a,b] = m1.map(Number);
    const c = Math.sqrt(a*a + b*b);
    return near(answer[0], c) ? {ok:true} : {ok:false, fix:[round(c, 2)]};
  }
  
  // 匹配：已知斜边和一直角边求另一直角边
  const m2 = stem.match(/直角三角形.*?斜边.*?(\d+).*?直角边.*?(\d+).*?另一直角边/);
  if(m2){
    const [,c,a] = m2.map(Number);
    const b = Math.sqrt(c*c - a*a);
    if(b > 0){
      return near(answer[0], b) ? {ok:true} : {ok:false, fix:[round(b, 2)]};
    }
  }
  
  return null;
}

// 导出所有验证器
module.exports = {
  verifyProfitLoss,
  verifyTreePlanting,
  verifyUnitRate,
  verifyGrassCow,
  verifyNumberTheory,
  verifyQuadraticFunction,
  verifyRightTriangle
};

// 使用说明
console.log(`
✅ 扩展验证规则已定义

新增验证器：
1. verifyProfitLoss - 盈亏问题
2. verifyTreePlanting - 植树问题
3. verifyUnitRate - 归一问题
4. verifyGrassCow - 牛吃草问题
5. verifyNumberTheory - 数论基础（质数、最大公约数、最小公倍数）
6. verifyQuadraticFunction - 二次函数（顶点、对称轴）
7. verifyRightTriangle - 解直角三角形（勾股定理）

这些验证器需要整合到 verify-all-topics.js 中的 pickVerifiers 函数。
`);

